/**
 * 
 */
package jvs.peer.io;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * @author qiangli
 *
 */
public class Channel {	
	private MessageDriver driver;

	private String id = null;
	
	private Header header = null;
	
	private MessageInputStream inputStream = null;
	
	private MessageOutputStream outputStream = null;

	protected long timestamp = System.currentTimeMillis();

	Channel(String id, MessageDriver driver) throws IOException {
		this.id = id;
		this.driver = driver;
		//
		inputStream = new MessageInputStream(this);
		outputStream = new MessageOutputStream(this);
	}

	public String getId() {
		return id;
	}

	public Header getHeader() {
		return header;
	}

	public void setHeader(Header header) {
		this.header = header;
	}

	public InputStream getInputStream() {
		return inputStream;
	}

	public OutputStream getOutputStream() {
		return outputStream;
	}

	public void shutdownInput() throws IOException {
		if (inputStream != null) {
			inputStream.close();
			inputStream = null;
		}
	}

	public void shutdownOutput() throws IOException {
		if (outputStream != null) {
			outputStream.close();
			outputStream = null;
		}
	}
	
	public void open() throws IOException {
		outputStream.open();
	}
	
	public void close() throws IOException {
		shutdownInput();
		shutdownOutput();
	}

	public void receive(Message msg) throws IOException {
		timestamp = System.currentTimeMillis();
		inputStream.receive(msg);
	}
	
	public String getJid() {
		return driver.getJid();
	}

	public String getPeer() {
		return getHeader().getPeer();
	}
	
	public void send(Message msg) throws Exception {
		msg.setHeader(this.getHeader());
		driver.send(msg);
		timestamp = System.currentTimeMillis();
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		Channel that = (Channel) obj;
		if (this.id == null) {
			if (that.id != null) {
				return false;
			}
		} else if (!this.id.equals(that.id)) {
			return false;
		}
		return true;
	}

	@Override
	public String toString() {
		return "Channel [driver=" + driver + ", id=" + id + ", header="
				+ header + ", timestamp=" + timestamp + "]";
	}

	public int getBufferSize() {
		return driver.getBufferSize();
	}
}
